package org.zoomdev.zoom.common.json;


import com.alibaba.fastjson2.JSONWriter;
import org.zoomdev.zoom.common.exceptions.ZoomException;
import org.zoomdev.zoom.common.io.Io;
import org.zoomdev.zoom.common.utils.DateTimeUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.reflect.Type;

public final class JSON {


    static {

        com.alibaba.fastjson2.JSON.config(JSONWriter.Feature.WriteNulls, false);
        com.alibaba.fastjson2.JSON.config(JSONWriter.Feature.WriteBooleanAsNumber, false);
        com.alibaba.fastjson2.JSON.configWriterDateFormat(DateTimeUtils.DATE_TIME_PATTERN);
        com.alibaba.fastjson2.JSON.configReaderDateFormat(DateTimeUtils.DATE_TIME_PATTERN);

    }


    public static String prettyStringify(Object value) {
        return com.alibaba.fastjson2.JSON.toJSONString(value, JSONWriter.Feature.PrettyFormat);
    }

    /**
     * 格式化json
     *
     * @param value
     * @return
     */
    public static String stringify(Object value) {
        try {
            return com.alibaba.fastjson2.JSON.toJSONString(value);
        } catch (Exception e) {
            throw new ZoomException(e);
        }
    }

    /**
     * 输出null
     * @param value
     * @param writeNulls
     * @return
     */
    public static String stringify(Object value,boolean writeNulls) {
        try {
            if(writeNulls){
                return com.alibaba.fastjson2.JSON.toJSONString(value,JSONWriter.Feature.WriteNulls);
            }else{
                return com.alibaba.fastjson2.JSON.toJSONString(value);
            }

        } catch (Exception e) {
            throw new ZoomException(e);
        }
    }

    public static void write(OutputStream os, Object value) {
        assert (os != null);
        try {
            com.alibaba.fastjson2.JSON.writeTo(os, value);
        } catch (Exception e) {
            throw new ZoomException(e);
        } finally {
            Io.close(os);
        }
    }


    public static <T> T parse(InputStream src, Type targetType) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, targetType);
        } catch (Exception e) {
            throw new ZoomException(e);
        } finally {
            Io.close(src);
        }
    }

    public static <T> T parse(Reader src, Type targetType) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, targetType);
        } catch (Exception e) {
            throw new ZoomException(e);
        } finally {
            Io.close(src);
        }
    }

    public static <T> T parse(String src, Type targetType) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, targetType);
        } catch (Exception e) {
            throw new ZoomException(e);
        }
    }


    /**
     * @param src
     * @param classOfT
     * @return
     */
    public static <T> T parse(InputStream src, Class<T> classOfT) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, classOfT);
        } catch (Exception e) {
            throw new ZoomException(e);
        } finally {
            Io.close(src);
        }
    }

    /**
     * @param src
     * @param classOfT
     * @return
     */
    public static <T> T parse(Reader src, Class<T> classOfT) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, classOfT);
        } catch (Exception e) {
            throw new ZoomException(e);
        } finally {
            Io.close(src);
        }
    }

    public static <T> T parse(String src, Class<T> classOfT) {
        try {
            return com.alibaba.fastjson2.JSON.parseObject(src, classOfT);
        } catch (Exception e) {
            throw new ZoomException(e);
        }
    }
}
